package com.sinvo.oa.util;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 */
public class TreeUtils {
    public static <T> List<T> listToTree(List<T> nodes, String parentIdField, String idField) {
        List<T> treeNodes = new ArrayList<>();
        for (T node : nodes) {
            Object parentIdValue = getFieldValue(node, parentIdField);
            int parentId = Integer.parseInt(parentIdValue.toString());
            if (parentId == 0) {
                // 父ID为0为根节点，直接加入列表中
                treeNodes.add(node);
                // 递归处理子节点
                setChildren(node, nodes, parentIdField, idField);
            }
        }
        return treeNodes;
    }

    private static <T> void setChildren(T parent, List<T> nodes, String parentIdField, String idField) {
        List<T> children = new ArrayList<>();
        for (T node : nodes) {
            Object parentIdValue = getFieldValue(node, parentIdField);
            int parentId = Integer.parseInt(parentIdValue.toString());
            Object idValue = getFieldValue(parent, idField);
            int id = Integer.parseInt(idValue.toString());
            if (parentId == id) {
                // 将节点加入对应的父节点中
                children.add(node);
                // 递归处理子节点
                setChildren(node, nodes, parentIdField, idField);
            }
        }
        if (!children.isEmpty()) {
            setFieldValue(parent, "children", children);
        }
    }

    /**
     * 反射获取对象的属性值
     * @param obj 目标对象
     * @param fieldName 属性名
     * @return 属性值
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private static Object getFieldValue(Object obj, String fieldName) {
        try {
            Class<?> clazz = obj.getClass();
            //java.lang.reflect.Field field = clazz.getDeclaredField(fieldName);
            //=============
            java.lang.reflect.Field field = null;
            try {
                field = clazz.getDeclaredField(fieldName);
            }catch (NoSuchFieldException e){
                field = clazz.getSuperclass().getDeclaredField(fieldName);
                field.setAccessible(true);
                return field.get(obj);
            }
            //==============
            field.setAccessible(true);
            return field.get(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 反射设置对象的属性值
     * @param obj 目标对象
     * @param fieldName 属性名
     * @param value 属性值
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private static void setFieldValue(Object obj, String fieldName, Object value) {
        try {
            Class<?> clazz = obj.getClass();
            java.lang.reflect.Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(obj, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
